/*
    SUSAN® - Sole of Unix Save ANything

   Copyright (C) 2014-2017 Skyatlas Co. CN
   Copyright (C) 2014-2020 Hechzh Property

   

   

   
*/
/*
 * Object Storage API device abstraction.
 *
 * Marco van Wieringen, February 2014
 */

#ifndef BAREOS_STORED_BACKENDS_DROPLET_DEVICE_H_
#define BAREOS_STORED_BACKENDS_DROPLET_DEVICE_H_

#include <droplet.h>
#include <droplet/vfs.h>

namespace storagedaemon {
/*
 * Generic callback for the droplet_device::walk_directory() function.
 *
 * Returns DPL_SUCCESS - success
 *         other dpl_status_t value: failure
 */
typedef dpl_status_t (*t_dpl_walk_directory_call_back)(dpl_dirent_t* dirent,
                                                       dpl_ctx_t* ctx,
                                                       const char* dirname,
                                                       void* data);
typedef dpl_status_t (*t_dpl_walk_chunks_call_back)(dpl_sysmd_t* sysmd,
                                                    dpl_ctx_t* ctx,
                                                    const char* chunkpath,
                                                    void* data);


class droplet_device : public chunked_device {
 private:
  /* maximun number of chunks in a volume (0000 to 9999) */
  const int max_chunks_ = 10000;
  char* configstring_{};
  const char* profile_{};
  const char* location_{};
  const char* canned_acl_{};
  const char* storage_class_{};
  const char* bucketname_{};
  dpl_ctx_t* ctx_{};
  dpl_sysmd_t sysmd_{};

  bool initialize();
  dpl_status_t check_path(const char* path);

  /*
   * Interface from chunked_device
   */
  bool CheckRemote() override;
  bool remote_chunked_volume_exists() override;
  bool FlushRemoteChunk(chunk_io_request* request) override;
  bool ReadRemoteChunk(chunk_io_request* request) override;
  ssize_t chunked_remote_volume_size() override;
  bool TruncateRemoteChunkedVolume(DeviceControlRecord* dcr) override;

  bool walk_directory(const char* dirname,
                      t_dpl_walk_directory_call_back callback,
                      void* data);
  bool walk_chunks(const char* dirname,
                   t_dpl_walk_chunks_call_back callback,
                   void* data,
                   bool ignore_gaps = false);

 public:
  droplet_device() = default;
  ~droplet_device();

  /*
   * Interface from Device
   */
  int d_close(int fd) override;
  int d_open(const char* pathname, int flags, int mode) override;
  int d_ioctl(int fd, ioctl_req_t request, char* mt = NULL) override;
  boffset_t d_lseek(DeviceControlRecord* dcr,
                    boffset_t offset,
                    int whence) override;
  ssize_t d_read(int fd, void* buffer, size_t count) override;
  ssize_t d_write(int fd, const void* buffer, size_t count) override;
  bool d_truncate(DeviceControlRecord* dcr) override;
  bool d_flush(DeviceControlRecord* dcr) override;
};
} /* namespace storagedaemon */
#endif /* OBJECTSTORE_DEVICE_H */
